﻿#region Using Directives

using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Text.RegularExpressions;
using Kongo.Properties;

#endregion Using Directives


namespace Kongo
{
    internal static class Helpers
    {
        #region Fields

        private static readonly Regex VariableValidatorRegex = new Regex("^[a-zA-Z0-9_.]+$");

        #endregion Fields


        #region Methods

        public static bool ConvertToBoolean(object value)
        {
            if (value != null)
            {
                // Is it already a boolean?
                if (value is bool)
                    return (bool)value;

                // Is it a string representation of true?
                string str = value.ToString();
                if(str.Equals("true", StringComparison.OrdinalIgnoreCase) || str.Equals("1"))
                    return true;
            }

            return false;
        }


        public static IList ConvertToList(object value)
        {
            if (value is IList)
            {
                return (IList)value;
            }
            else if (value is ICollection)
            {
                ArrayList list = new ArrayList((ICollection)value);
                return list;
            }
            else if (value is IEnumerable)
            {
                List<object> list = new List<object>();
                IEnumerator enumerator = ((IEnumerable)value).GetEnumerator();
                while (enumerator.MoveNext())
                    list.Add(enumerator.Current);
            }

            return null;
        }


        public static string Format(string format, params object[] args)
        {
            // Wrapper that always uses the current culture
            return String.Format(CultureInfo.CurrentCulture, format, args);
        }


        public static void ThrowIfNull(object value, string paramName)
        {
            if (value == null)
            {
                if (String.IsNullOrEmpty(paramName))
                    throw new ArgumentException();

                throw new ArgumentNullException(paramName);
            }
        }


        public static void ThrowIfNullOrEmpty(string value, string paramName)
        {
            ThrowIfNull(value, paramName);
            if (value.Length == 0)
            {
                if (String.IsNullOrEmpty(paramName))
                    throw new ArgumentException(Resource.Argument_EmptyString);

                throw new ArgumentException(Resource.Argument_EmptyString, paramName);
            }
        }


        public static bool TryConvertToLong(object o, out long value)
        {
            if (o == null)
            {
                value = default(long);
                return false;
            }

            //switch(


            value = default(long);
            return true;
        }


        public static bool IsTrue(Context context, Variable variable)
        {
            // Return true if variable exists and is not empty.
            // If the variable is a boolean, return its value.

            object value;
            if (variable.TryEvaluate(context, out value))
            {
                if (value != null)
                {
                    if (value is bool)
                        return (bool)value;

                    return true;
                }
            }

            return false;
        }


        // TODO Should this be public for custom tag/filter creators?
        public static string UnescapeStringConstant(string value)
        {
            // Remove the opening and closing quotes
            // and covert the escape sequences

            return
                value.Substring(1, value.Length - 2)
                .Replace("\\t", "\t")
                .Replace("\\n", "\n")
                .Replace("\\r", "\r")
                .Replace("\\\"", "\"")
                .Replace("\\\\", "\\");
        }

        #endregion Methods


        #region Properties

        public static string AssemblyCopyright
        {
            get
            {
                object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false);
                if (attributes.Length > 0)
                    return ((AssemblyCopyrightAttribute)attributes[0]).Copyright ?? String.Empty;

                return String.Empty;
            }
        }


        public static string AssemblyTitle
        {
            get
            {
                object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false);
                if (attributes.Length > 0)
                {
                    AssemblyTitleAttribute titleAttribute = (AssemblyTitleAttribute)attributes[0];
                    if (!String.IsNullOrEmpty(titleAttribute.Title))
                        return titleAttribute.Title;
                }

                // Use the assembly name
                return Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().CodeBase);
            }
        }



        public static string AssemblyVersion
        {
            get { return Assembly.GetExecutingAssembly().GetName().Version.ToString(); }
        }

        #endregion Properties
    }
}
